<template>
  <div class="mp-menu mp-menu__edit">
    <div>
      <div class="mp-menu__preview mp-menu_preview_area">
        <div class="mp-menu__preview-hd"></div>
        <div class="mp-menu__preview-bd">
          <div class="mp-menu__preview-bottom">
            <div class="mp-menu__keyboard">
              <div class="mp-menu__keyboard-icon"></div>
            </div>
            <div class="mp-menu__preview-line line__no-menu"></div>
            <div class="mp-menu__edit-add" :class="{'add__no-menu':!menus.length}">
              <div v-if="menus.length" class="mp-menu__list-wrap">
                <li v-for="(m,index) in menus" :class="{'mp-menu_current':index===currentIndex && currentSubIndex===undefined}" @click.stop="rootMenuClick(m,index)">
                  <div class="mp-menu__preview-line"></div>
                  {{ m.name }}
                  <div class="mp-menu__sub_box" v-if="index===currentIndex">
                    <ul class="sub__pre-menu-list">
                      <li v-for="(sm,sindex) in m.sub_button" :class="{'mp-menu_current':sindex===currentSubIndex}" @click.stop="subMenuClick(sm,sindex)">
                        {{ sm.name }}
                      </li>
                      <li v-if="m.sub_button && m.sub_button?.length < 5" @click.stop="newSubMenu">
                        <i class="mp-menu__add-icon"></i> 添加
                      </li>
                    </ul>
                    <i class="arrow arrow_out"></i>
                    <i class="arrow arrow_in"></i>
                  </div>
                </li>
                <li v-if="menus.length<3" @click="newRootMenu">
                  <div class="mp-menu__preview-line"></div>
                  <a title="最多添加3个一级菜单" class="pre_menu_link js_addL1Btn">
                    <i class="mp-menu__add-icon"></i>
                  </a>
                </li>
              </div>
              <div v-else class="mp-menu__add-menu" @click="newRootMenu">
                <div class="mp-menu__add-icon"></div>
                <span>添加菜单</span>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="mp-menu__right_container">
      <div class="mp-menu__content">
        <div v-if="editMenu">
          <h3>菜单信息</h3>
          <form class="mp-menu__form-container">
            <div class="mp-menu-form__control-group">
              <label class="mp-menu-form__label">名称</label>
              <div class="mp-menu-form__controls">
                <input v-model.trim="editMenu.name" type="text" placeholder="仅支持中英文和数字" class="mp-menu-form__input">
                <p class="mp-menu-form__tips" v-if="currentSubIndex !== undefined">仅支持中英文和数字，字数不超过8个汉字或16个字母。</p>
                <p class="mp-menu-form__tips" v-else>仅支持中英文和数字，字数不超过4个汉字或8个字母。</p>
              </div>
            </div>
            <div class="mp-menu-form__control-group">
              <label class="mp-menu-form__label">消息类型</label>
              <div class="mp-menu-form__controls" style="padding-top: 10px">
                <div class="mp-menu-form__radio-group">
                  <div class="mp-menu-form__radio">
                    <input id="typeView" v-model="editMenu.type" type="radio" name="type" :value="Type.view"/>
                    <label for="typeView">链接</label>
                  </div>
                  <div class="mp-menu-form__radio">
                    <input id="typeClick" v-model="editMenu.type" type="radio" name="type" :value="Type.click"/>
                    <label for="typeClick">点击</label>
                  </div>
                  <div class="mp-menu-form__radio">
                    <input id="typeMn" v-model="editMenu.type" type="radio" name="type" :value="Type.miniprogram"/>
                    <label for="typeMn">小程序</label>
                  </div>
                </div>
              </div>
            </div>
            <div class="mp-menu-form__control-group" v-if="Type.click === editMenu.type">
              <label class="mp-menu-form__label">KEY值</label>
              <div class="mp-menu-form__controls">
                <input v-model.trim="editMenu.key" type="text" placeholder="不超过128字节" class="mp-menu-form__input">
                <p class="mp-menu-form__tips">菜单KEY值，用于消息接口推送，不超过128字节</p>
              </div>
            </div>
            <div class="mp-menu-form__control-group" v-else-if="Type.view === editMenu.type">
              <label class="mp-menu-form__label">网页链接</label>
              <div class="mp-menu-form__controls">
                <input v-model.trim="editMenu.url" type="text" placeholder="不超过1024字节" class="mp-menu-form__input">
                <p class="mp-menu-form__tips">网页链接，用户点击菜单可打开链接，不超过1024字节</p>
              </div>
            </div>
            <template v-else>
              <div class="mp-menu-form__control-group">
                <label class="mp-menu-form__label">appid</label>
                <div class="mp-menu-form__controls">
                  <input v-model.trim="editMenu.appid" type="text" placeholder="小程序的appid" class="mp-menu-form__input">
                  <p class="mp-menu-form__tips">必须是公众号已绑定的小程序的appid</p>
                </div>
              </div>
              <div class="mp-menu-form__control-group">
                <label class="mp-menu-form__label">页面路径</label>
                <div class="mp-menu-form__controls">
                  <input v-model.trim="editMenu.pagepath" type="text" placeholder="小程序的页面路径" class="mp-menu-form__input">
                  <p class="mp-menu-form__tips">小程序存在的页面路径</p>
                </div>
              </div>
            </template>
          </form>
        </div>
        <div v-else>你未添加自定义菜单，点击左侧添加菜单为公众号创建菜单栏。</div>
      </div>
      <div class="mp-menu__edit-action-bar">
        <div class="mp-menu__edit-action-inner">
          <div class="mp-menu__edit-button">
            <div>
              <a class="mp-menu__action" @click="rmItem" v-if="editMenu">删除菜单</a>
              <template v-if="currentIndex!==undefined && currentSubIndex===undefined">
                <span style="margin: 0 10px">|</span>
                <a class="mp-menu__action" @click="rootMove(-1)" v-if="currentIndex>0">←左移</a>
                <a class="mp-menu__action" @click="rootMove(1)" v-if="currentIndex<menus?.length-1">右移→</a>
              </template>
              <template v-if="currentIndex!==undefined && currentSubIndex!==undefined">
                <span style="margin: 0 10px">|</span>
                <a class="mp-menu__action" @click="subMove(-1)" v-if="currentSubIndex > 0">↑上移</a>
                <a class="mp-menu__action" @click="subMove(1)" v-if="currentSubIndex < rootCurrentMenu.sub_button.length-1">下移↓</a>
              </template>
            </div>
            <div class="weui-desktop-btn_wrp">
              <button @click="doPub" type="button" class="weui-desktop-btn weui-desktop-btn_primary">保存并发布</button>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import {computed, defineOptions, Ref, ref} from "vue";

enum Type {view = 'view', click = 'click', miniprogram = 'miniprogram'};

type Menu = {
  name: string;
  type: Type;
  key?: string | undefined | null;
  url?: string | undefined | null;
  appid?: string | undefined | null;
  pagepath?: string | undefined | null;
  sub_button?: Array<Menu> | undefined | null;
};

defineOptions({
  name: "MpMenu"
})

const emits = defineEmits<{
  (event: 'submit', buttons: Menu[]): void
}>();

const props = defineProps<{
  buttons: Array<Menu> | undefined
}>();

const menus: Ref<Array<Menu>> = ref<Array<Menu>>([])

if (props.buttons) {
  menus.value = JSON.parse(JSON.stringify(props.buttons));
}

const currentIndex: Ref<number | undefined> = ref<number>()
const currentSubIndex: Ref<number | undefined> = ref<number>()

const currentMenu: Ref<Menu | undefined> = ref<Menu>();
const rootCurrentMenu: Ref<Menu | undefined> = ref<Menu>();

const editMenu: Ref<Menu | undefined> = computed(() => {
  if (currentMenu.value) {
    return currentMenu.value;
  }
  return rootCurrentMenu.value;
});

const newRootMenu = () => {
  if (menus.value.length < 3) {
    menus.value.push({
      name: '菜单名称',
      type: Type.view,
      url: "",
      appid: "",
      pagepath: "",
      sub_button: []
    })
    currentMenu.value = undefined;
    rootCurrentMenu.value = menus.value[menus.value.length - 1];
    currentIndex.value = menus.value.length - 1;
    currentSubIndex.value = undefined;
  }
}

const newSubMenu = () => {
  let subButton = rootCurrentMenu.value?.sub_button;

  if (subButton && subButton.length < 5) {
    subButton.push({
      name: '子菜单名称',
      type: Type.view,
      url: "",
      appid: "",
      pagepath: ""
    })

    currentMenu.value = subButton[subButton.length - 1];
    currentSubIndex.value = subButton.length - 1;
  }
}

const rootMenuClick = (m: Menu, index: number) => {
  rootCurrentMenu.value = m;
  currentMenu.value = undefined;
  currentIndex.value = index;
  currentSubIndex.value = undefined;
}

const subMenuClick = (sm: Menu, sindex: number) => {
  currentMenu.value = sm;
  currentSubIndex.value = sindex;
}

const doPub = () => {
  emits('submit', JSON.parse(JSON.stringify(menus.value)))
}

const rmItem = () => {
  if (currentIndex.value !== undefined && currentSubIndex.value === undefined) {
    menus.value.splice(currentIndex.value, 1);
    menus.value = JSON.parse(JSON.stringify(menus.value));
    if (menus.value[0]) {
      rootCurrentMenu.value = menus.value[0];
      currentIndex.value = 0;
    } else {
      rootCurrentMenu.value = undefined;
      currentIndex.value = undefined;
    }
  } else if (currentIndex.value !== undefined && currentSubIndex.value !== undefined) {
    rootCurrentMenu.value.sub_button.splice(currentSubIndex.value, 1);
    rootCurrentMenu.value.sub_button = JSON.parse(JSON.stringify(rootCurrentMenu.value.sub_button));
    if (rootCurrentMenu.value.sub_button[0]) {
      currentMenu.value = rootCurrentMenu.value.sub_button[0];
      currentSubIndex.value = 0;
    } else {
      currentMenu.value = undefined;
      currentSubIndex.value = undefined;
    }
  }
}

const rootMove = (dir: number) => {
  let rootMenu = menus.value;
  let next = currentIndex.value + dir;

  if (dir < 0) {
    if (currentIndex.value != 0) {
      rootMenu[currentIndex.value] = rootMenu.splice(currentIndex.value - 1, 1, rootMenu[currentIndex.value])[0];
    } else {
      rootMenu.push(rootMenu.shift());
    }
  } else {
    if (currentIndex.value != rootMenu.length - 1) {
      rootMenu[currentIndex.value] = rootMenu.splice(currentIndex.value + 1, 1, rootMenu[currentIndex.value])[0];
    } else {
      rootMenu.unshift(rootMenu.splice(currentIndex.value, 1)[0]);
    }
  }
  currentIndex.value = next;
  rootCurrentMenu.value = rootMenu[next];
}
const subMove = (dir: number) => {
  let subButton = rootCurrentMenu.value.sub_button;
  let next = currentSubIndex.value + dir;

  if (dir < 0) {
    if (currentSubIndex.value != 0) {
      subButton[currentSubIndex.value] = subButton.splice(currentSubIndex.value - 1, 1, subButton[currentSubIndex.value])[0];
    } else {
      subButton.push(subButton.shift());
    }
  } else {
    if (currentSubIndex.value != subButton.length - 1) {
      subButton[currentSubIndex.value] = subButton.splice(currentSubIndex.value + 1, 1, subButton[currentSubIndex.value])[0];
    } else {
      subButton.unshift(subButton.splice(currentSubIndex.value, 1)[0]);
    }
  }
  currentSubIndex.value = next;
  currentMenu.value = subButton[next];
}

</script>

<style lang="less">
.mp-menu {
  font-size: 14px;

  &__action {
    cursor: pointer;
    margin-right: 5px;

    &:hover {
      color: #07C160;
    }
  }

  ul {
    margin: 0;
    padding: 0;
  }

  .sub__pre-menu-list {
    border: 1px;
    color: #616161;

    li {
      width: auto;
      font-size: 12px;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
      word-wrap: normal;
    }
  }

  &__sub_box {
    position: absolute;
    left: 0;
    width: 100%;
    bottom: 80px;
    background-color: #fff;
    border: 1px solid #e3e4e5;
    border-top-width: 0;
    border-radius: 4px;

    li {
      height: 48px !important;
      border-top: 1px solid #E7E7EB;
    }

    .arrow {
      position: absolute;
      left: 50%;
      margin-left: -6px;

      &_out {
        bottom: -6px;
        display: inline-block;
        width: 0;
        height: 0;
        border-width: 6px;
        border-style: dashed;
        border-color: transparent;
        border-bottom-width: 0;
        border-top-color: #D0D0D0;
        border-top-style: solid;
      }

      &_in {
        bottom: -5px;
        display: inline-block;
        width: 0;
        height: 0;
        border-width: 6px;
        border-style: dashed;
        border-color: transparent;
        border-bottom-width: 0;
        border-top-color: #FAFAFA;
        border-top-style: solid;
      }
    }
  }

  &_current {
    border: 1.5px solid #07c160 !important;
    background-color: rgba(7, 193, 96, 0.05);
    color: #07C160;
  }

  &__list-wrap {
    display: flex;
    width: 100%;

    li {
      list-style: none;
      flex: 1;
      height: 100%;
      display: flex;
      justify-content: center;
      align-items: center;
      position: relative;
      cursor: pointer;
      font-size: 13px;
    }


    .pre_menu_item {
      position: relative;
      float: left;
      line-height: 38px;
      text-align: center
    }

    .pre_menu_item .icon_menu_dot {
      width: 7px;
      height: 7px;
      vertical-align: middle;
      display: inline-block;
      margin-right: 2px;
      margin-top: -2px;
    }

    .pre_menu_item a {
      display: block;
      width: auto;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
      word-wrap: normal;
      color: #616161;
      text-decoration: none
    }

    .pre_menu_link:hover {
      color: #353535
    }
  }

  &__form-container {
    margin-top: 32px;
  }

  &-form {
    &__control-group {
      display: flex;
      align-items: flex-start;
      margin-bottom: 30px;
    }

    &__radio {
      display: flex;
      align-items: center;
      margin-right: 30px;

      input[type="radio"] {
        margin: 0;
        padding: 0;
        cursor: pointer;
      }

      label {
        padding-left: 10px;
        vertical-align: sub;
        cursor: pointer;
      }

      &-group {
        display: flex;
      }
    }

    &__controls {
      flex: 1;
    }

    &__label {
      width: 100px;
      margin-top: 10px;
    }

    &__input {
      display: table-cell;
      width: 100%;
      padding: 10px 12px;
      box-sizing: border-box;
      background: #fff;
      border: 1px solid #E3E4E5;
      border-radius: 4px;
      color: #1A1B1C;

      &:focus {
        outline: 0;
        border-color: #07C160;
      }
    }

    &__tips {
      margin: 0;
      padding-top: 8px;
      color: #7E8081;
    }
  }

  &__add-menu {
    height: 100%;
    width: 100px;
    display: -webkit-box;
    display: -webkit-flex;
    display: -ms-flexbox;
    display: flex;
    justify-content: center;
    align-items: center;
    margin: 0 auto;
    cursor: pointer;

    span {
      color: #07c160;
    }
  }

  &__add-icon {
    background: url("icon/add.svg");
    width: 20px;
    height: 17px;
    vertical-align: middle;
    display: inline-block;
  }

  &__keyboard {
    width: auto;
    height: 100%;
    padding: 0 2px;

    &-icon {
      width: 40px;
      height: 100%;
      background: url("icon/keyboard.svg");
    }
  }

  &__edit {
    display: flex;

    h3 {
      padding: 0;
      margin: 0;
    }

    &-add {
      display: flex;
      flex: 1;
      height: 100%;
    }

    .add__no-menu {
      line-height: 64px;
      border: 2px dashed rgba(7, 193, 96, 0.6);
      border-radius: 2px;
      flex: 1;
    }

    .weui-desktop-btn {
      outline: none;
      padding: 0 24px;
      min-width: 120px;
      box-sizing: border-box;
      line-height: 36px;
      vertical-align: middle;
      text-align: center;
      text-decoration: none;
      border-radius: 4px;
      font-size: 14px;
      letter-spacing: 1px;
      cursor: pointer;
      border-width: 0;
      border-style: solid;
      position: relative;

      &:hover:before {
        content: "";
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        border-radius: inherit;
        background: rgba(0, 0, 0, 0.05);
      }
    }

    .weui-desktop-btn_default {
      color: #1A1B1C;
      border: 1px solid #E3E4E5;
    }

    .weui-desktop-btn_primary {
      background-color: #07C160;
      color: #FFFFFF;
    }

    &-action-bar {
      background-color: rgba(0, 0, 0, 0);
      z-index: 100;
      border-top: 1px solid rgba(0, 0, 0, 0.02);
      position: sticky;
      bottom: 0;
    }

    &-action-inner, &-action-bar {
      background-color: #ffffff;
      height: 80px;
      margin-left: auto;
      margin-right: auto;
      border-radius: 0 0 6px 6px;
      box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.02)
    }

    &-save {
      margin-right: 16px;
    }

    &-button {
      height: 100%;
      display: -webkit-box;
      display: -webkit-flex;
      display: -ms-flexbox;
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding-right: 40px;
      padding-left: 40px;
    }
  }

  &__right_container {
    flex: 1;
    height: 100%;
  }

  &__preview {
    border-radius: 8px;
    width: 300px;
    background-color: #fdfdfd;
    margin-right: 24px;
    box-sizing: border-box;
    max-height: 634px;
    box-shadow: 0 1px 5px 0 rgba(0, 0, 0, 0.05);
    flex-shrink: 0;

    .mp-menu__preview-line {
      position: absolute;
      width: 0.5px;
      height: 33px;
      background: #e3e4e5;
      left: 0;
      bottom: 15px;
      right: 0;
    }

    &-hd {
      background-image: url("icon/hd.png");
      background-size: cover;
      height: 70px;
    }

    &-bd {
      height: 480px;
      position: relative;
      background-color: #fdfdfd;
      border-radius: 0 0 8px 8px;
    }

    &-bottom {
      position: absolute;
      left: 0;
      bottom: 0;
      width: 100%;
      height: 68px;
      display: -webkit-box;
      display: -webkit-flex;
      display: -ms-flexbox;
      display: flex;
      justify-content: space-between;
      box-shadow: inset 0px 0.5px 0px #e3e4e5;
      align-items: center;
      background-color: #fff;
      border-radius: 0 0 8px 8px;
    }

    &-line {
      position: absolute;
      width: 0.5px;
      height: 33px;
      background: #e3e4e5;
      left: 0;
      bottom: 15px;
      right: 0;
    }

    .line__no-menu {
      left: 44px;
    }
  }

  &__content {
    border-radius: 8px 8px 0 0;
    background-color: #fff;
    box-shadow: 0 1px 5px 0 rgba(0, 0, 0, 0.05);
    padding: 40px
  }
}
</style>